package com.yuan.yblog.portal.listener;

import com.yuan.yblog.common.consts.RedisKey;
import com.yuan.yblog.common.service.EntityCacheService;
import com.yuan.yblog.common.utils.SpringUtils;
import com.yuan.yblog.common.utils.StringUtils;
import com.yuan.yblog.portal.config.RabbitmqConfig;
import com.yuan.yblog.portal.pojo.DTO.MysqlMessage;
import com.yuan.yblog.portal.service.AuthenticationService;
import com.yuan.yblog.security.pojo.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * @author hepeiyuan on 2024/6/1 19:35
 * @description mysql-es 数据同步监听器
 */
@Component
@Slf4j
public class MysqlRedisSynchronizationListener {

    @Autowired
    EntityCacheService entityCacheService;

    @Value("${jwt.expiration}")
    private Long jwtExpiration;

    @Autowired
    AuthenticationService authenticationService;


    @RabbitListener(queues = {RabbitmqConfig.QUEUE_REDIS_MYSQL_CHANGE_SYNC})
    public void consume(MysqlMessage message) {
        if (message == null) {
            return;
        }
        if (MysqlMessage.OperationType.UPDATE.equals(message.getOperationType())
                ||MysqlMessage.OperationType.DELETE.equals(message.getOperationType())) {
            // 数据发生变化，删除缓存
            deleteEntityCache(message);
        }
        if (message.getTableName().equals("user")) {
            // 用户信息发生变化，判断是否重建“登录信息”
            LoginUser loginUser = (LoginUser) entityCacheService.getEntity(
                    RedisKey.AUTH_LOGIN_USER,
                    message.getId(), jwtExpiration);
            if (loginUser != null) {
                // 用户已登录，重建登录信息
                authenticationService.buildLoginUser(loginUser);
            }

        }
    }

    /**
     * 删除缓存
     * @param message 消息对象
     */
    private void deleteEntityCache(MysqlMessage message) {
        // 获取数据表的小驼峰名字
        String tableName = StringUtils.toCamelCase(message.getTableName());
        // 获取数据表对应的【服务类对象】
        String serviceBeanName =  tableName + "ServiceImpl";
        Object service = SpringUtils.getBean(serviceBeanName);
        // 通过【反射】获取成员变量，得到缓存key
        String redisKey = null;
        Field[] fields = service.getClass().getFields();
        for(Field field : fields){
            if (field.getName().equals(tableName.toUpperCase())) {
                try {
                    redisKey = String.valueOf(field.get(service));
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("消息队列删除缓存出错：" + e);
                }
                log.info("缓存key = "+field.getName()+", value = "+redisKey);
                break;
            }
        }
        // 删除缓存
        if(!StringUtils.isEmpty(redisKey)) {
            entityCacheService.deleteEntity(redisKey, message.getId());
        }
    }
}

